Skip to main content

Extract filename and extension from path - 1

Shell script that takes care of

  • Absolute paths
  • Relative paths (including ./ or ../)
  • Files with multiple dots (e.g., data.v1.2.tar.gz)
  • Files without an extension (e.g., README, script)
  • Paths ending with a slash (e.g., /var/log/)
  • Paths with special characters and spaces
  • Empty base names from directory paths like /home/user/

Bash Script: extract_name_extension.sh

#!/bin/bash

# Function to extract file name and extension
extract_name_ext() {
local filepath="$1"

# Extract the base name (file name without directory)
local base_name="${filepath##*/}"
# Trim any trailing slashes from the base name
base_name="${base_name%/}"

if [[ -z "$base_name" ]]; then
echo "File name: "
echo "Extension: "
return
fi

# Extract extension (last part after the last dot)
local extension="${base_name##*.}"
local file_name="${base_name%.*}"

# If no dot was found, set extension to empty
if [[ "$file_name" == "$base_name" ]]; then
extension=""
fi

echo "File name: $file_name"
echo "Extension: $extension"
}

# Main script execution
if [ $# -ne 1 ]; then
echo "Usage: $0 <file_path>"
exit 1
fi

extract_name_ext "$1"

Example Usage

$ ./extract_name_extension.sh /home/user/data.v1.2.tar.gz
File name: data.v1.2.tar
Extension: gz

$ ./extract_name_extension.sh README
File name: README
Extension:

$ ./extract_name_extension.sh images/photo.jpg
File name: photo
Extension: jpg

$ ./extract_name_extension.sh my\ file\ with\ spaces.txt
File name: my file with spaces
Extension: txt

$ ./extract_name_extension.sh /var/log/
File name:
Extension:

$ ./extract_name_extension.sh .
File name:
Extension:

$ ./extract_name_extension.sh .bashrc
File name: .
Extension: bashrc

$ ./extract_name_extension.sh file.tar.gz.bak
File name: file.tar.gz
Extension: bak

Explanation of Key Components

  • ${filepath##*/}: Extracts the base filename (ignoring directory part).
  • ${base_name%/}: Removes any trailing slash from the base name.
  • ${base_name##*.} and ${base_name%.*}:
    • Used to extract the extension and file name by splitting at the last dot.
  • if [[ "$file_name" == "$base_name" ]]: Checks if there was no extension, in which case we set extension="".

Why This Works

This script is robust against various edge cases:

  • It handles paths with multiple dots correctly by focusing on the last dot.
  • It safely trims trailing slashes from file names.
  • It supports filenames and paths with spaces, special characters (like #, @, etc.), and even empty base names.

Requirements

This script uses only standard Bash built-in features and does not depend on external tools. It works across all Unix-like systems, including Linux and macOS.